#!/usr/bin/python
#   = the beging of a row
# \n = the end of a row
# + = the end of a map (not currently reflected by the program)
# S = the X,Y of where you start, zero based
# E = the X,Y of where you end, zero based
# - = the X,Y of any free space you can move to that costs 1
#
import pprint
import random
import getopt
import sys


known_types = ['S','E']

def gen_map(size_x,size_y):
  # generate a map of at least 2x2
  # populate a (S)tart and (E)nd
  if size_x*size_y < 4:
    return None
  
  amap = []
  for i in range(size_x):
    amap.append([])
    for j in range(size_y):
      amap[i].append('-')

  # pick a random start 
  s_x,s_y = gen_xy_dot(size_x,size_y)
  while True:
    # pick a random end that's not the start
    e_x,e_y = gen_xy_dot(size_x,size_y)
    if is_xy_safe(amap,e_x,e_y):
      break;

  amap[s_x][s_y] = 'S'
  amap[e_x][e_y] = 'E'
  
  # bam. map
  return amap

def gen_xy_dot(range_x,range_y):
  # pick a random dot
  ret_x = random.randint(0,range_x-1)
  ret_y = random.randint(0,range_y-1)

  return [ret_x,ret_y]

def is_xy_safe(amap,x_value,y_value):
  # checks if the X Y is a li
  x,y = x_y_size_map(amap)
  if x_value <= x and y_value <= y:
    curr = amap[x_value][y_value]
    if curr not in known_types:
      return True
    return False

def add_to_known_stuff_types(stuff):
  for s in list(stuff):
    if s not in known_types:
      known_types.append(s)
    else:
      print "Skipping ",s," because it's already a known type you moron"

def add_stuff(amap,stuff_type):
  # randomly add stuff of type "stuff_type"
  # potentially fill half of the map with crap
  x,y = x_y_size_map(amap)
  max_populate = ((x-1)*(y-1)) / 2
  
  num_stuffs = random.randint(1,max_populate)

  for n in range(num_stuffs):
    m_x,m_y = gen_xy_dot(x,y)
    if is_xy_safe(amap,m_x,m_y):
      amap[m_x][m_y] = stuff_type

def x_y_size_map(amap):
  # determine the size of a map using stupid python hacks
  i = [len(y) for y in amap]
  x = len(i)
  y = len(y)

  return [x,y]

def print_map(amap):
  # print the map into something useful
  if amap:
    x,y = x_y_size_map(amap)

    for i in range(x):
      print ''.join(amap[i])
  else:
    print "can't print a blank map you idiot"

def usage():
  print "usage: ",sys.argv[0]," -x # -y # -s \"WM*\""
  print "-x: x dimensions > 2"
  print "-y: y dimensions > 2"
  print "-s: list of stuff in string format,e.g.: \"WM*\""
  sys.exit(2)

def main():

  size_x = 0
  size_y = 0
  stuff = ""
  
  try:
    opts, args = getopt.getopt(sys.argv[1:], "hx:y:s:", ["help","sizex=","sizey=","stuff="])
  except getopt.GetoptError:
    usage()
    sys.exit(2)

  for opt, arg in opts:
    if opt in ("-h", "--help"):
      usage()
      sys.exit()
    elif opt in ("-x","--sizex"):
      size_x = int(arg)
    elif opt in ("-y","--sizey"):
      size_y = int(arg)
    elif opt in ("-s","--stuff"):
      #stuff string
      stuff = arg

  #validate they've not asked for something dumb
  if size_y <= 2 or size_x <= 2:
    print "your map will be stupid, stupid"
    usage()

  if size_y == 0 or size_x == 0:
    print "you need both an x and y"
    usage()

  if len(stuff) < 1:
    # we need some stuff, add some walls for those jerks
    stuff = "W"

  # ok, they've got a decent request, generate a map
  my_map = gen_map(size_y,size_x)

  # alright, now lets add their stuff
  if stuff != "":
    add_to_known_stuff_types(stuff)
    for s in list(stuff):
      add_stuff(my_map,s)

  # done, vomit map
  print_map(my_map)

if __name__ == "__main__":
    main()
